package org.ricks.common.db;

import org.ricks.db.BeanProcessor;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.*;

/**
 * @author chenwei
 * @Title:
 * @Package
 * @Description:
 * @date 2020/12/2316:43
 */
public class BasicRowProcessor implements RowProcessor {
    private static final BeanProcessor defaultConvert = new BeanProcessor();
    private static final BasicRowProcessor instance = new BasicRowProcessor();
    private final BeanProcessor convert;

    /** @deprecated */
    @Deprecated
    public static BasicRowProcessor instance() {
        return instance;
    }

    public BasicRowProcessor() {
        this(defaultConvert);
    }

    public BasicRowProcessor(BeanProcessor convert) {
        this.convert = convert;
    }

    public Object[] toArray(ResultSet rs) throws SQLException {
        ResultSetMetaData meta = rs.getMetaData();
        int cols = meta.getColumnCount();
        Object[] result = new Object[cols];

        for(int i = 0; i < cols; ++i) {
            result[i] = rs.getObject(i + 1);
        }

        return result;
    }

    public <T> T toBean(ResultSet rs, Class<? extends T> type) throws SQLException {
        return this.convert.toBean(rs, type);
    }

    public <T> List<T> toBeanList(ResultSet rs, Class<? extends T> type) throws SQLException {
        return this.convert.toBeanList(rs, type);
    }

    public Map<String, Object> toMap(ResultSet rs) throws SQLException {
        Map<String, Object> result = new CaseInsensitiveHashMap();
        ResultSetMetaData rsmd = rs.getMetaData();
        int cols = rsmd.getColumnCount();

        for(int i = 1; i <= cols; ++i) {
            String columnName = rsmd.getColumnLabel(i);
            if (null == columnName || 0 == columnName.length()) {
                columnName = rsmd.getColumnName(i);
            }

            result.put(columnName, rs.getObject(i));
        }

        return result;
    }

    private static class CaseInsensitiveHashMap extends LinkedHashMap<String, Object> {
        private final Map<String, String> lowerCaseMap;
        private static final long serialVersionUID = -2848100435296897392L;

        private CaseInsensitiveHashMap() {
            this.lowerCaseMap = new HashMap();
        }

        public boolean containsKey(Object key) {
            Object realKey = this.lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH));
            return super.containsKey(realKey);
        }

        public Object get(Object key) {
            Object realKey = this.lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH));
            return super.get(realKey);
        }

        public Object put(String key, Object value) {
            Object oldKey = this.lowerCaseMap.put(key.toLowerCase(Locale.ENGLISH), key);
            Object oldValue = super.remove(oldKey);
            super.put(key, value);
            return oldValue;
        }

        public void putAll(Map<? extends String, ?> m) {
            Iterator var2 = m.entrySet().iterator();

            while(var2.hasNext()) {
                Map.Entry<? extends String, ?> entry = (Map.Entry)var2.next();
                String key = (String)entry.getKey();
                Object value = entry.getValue();
                this.put(key, value);
            }

        }

        public Object remove(Object key) {
            Object realKey = this.lowerCaseMap.remove(key.toString().toLowerCase(Locale.ENGLISH));
            return super.remove(realKey);
        }
    }
}
